#include "stdafx.h"
#include "libraries.h"

#include "Log.h"
#include "FileLogListener.h"
#include "Timer.h"
#include "StaticHashMap.h"

using namespace Cvekas;

template <typename Val, typename Key, size_t size>
void testInsertion(StaticHashMap<Val, Key, size>& hash_map, uint n)
{
	uint id[2] = {0, 0};
	TimeStamp t1 = Timer::getTimeStamp();
	for(uint i = 0; i < n; ++i)
	{
		id[0] = i;
		id[1] = i;

		hash_map.set(rand(), id);
	}
	TimeStamp t2 = Timer::getTimeStamp();
	t2 -= t1;
	LOG(FORMAT("Inserted %u items: %d us", % n % t2.toMicroSec())); 
}

template <typename Val, typename Key, size_t size>
void testRetrieval(StaticHashMap<Val, Key, size>& hash_map, uint n, uint item_count)
{
	uint sum = 0;
	uint id[2] = {0, 0};
	TimeStamp t1 = Timer::getTimeStamp();
	for(uint i = 0; i < n; ++i)
	{
		id[0] = rand() % item_count;
		id[1] = id[0];

		sum += hash_map.at(id);
	}
	TimeStamp t2 = Timer::getTimeStamp();
	t2 -= t1;
	LOG(FORMAT("Retrieved %u items from %u: %d us. Sum: %u", % n % item_count % t2.toMicroSec() % sum)); 
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nShowCmd)
{
	Log::init();
	Log::addListener(FileLogListenerPtr(new FileLogListener("StaticHashMapTest.log")));

	StaticHashMap<uint, uint[2], 10000> hash_map0, hash_map1, hash_map2(9000);

	srand(666);

	Timer::reset();

	// Insertion
	testInsertion(hash_map0, 2500);
	testInsertion(hash_map1, 5000);
	testInsertion(hash_map2, 9000);
	
	// Retrieval
	testRetrieval(hash_map0, 100000, 2500);
	testRetrieval(hash_map1, 100000, 5000);
	testRetrieval(hash_map2, 100000, 9000);

	Log::release();
	return 0;
}